package rpcpool

import (
	"cowb/log"
	"net"
	"net/rpc"
	"reflect"
	"sync"
	"time"
)

var rwRPCs sync.RWMutex
var rpcs map[string]*rpc.Client

func init() {
	rpcs = make(map[string]*rpc.Client)
}

func Listen(host string, service interface{}) {
	msgType := reflect.TypeOf(service)
	if msgType == nil || msgType.Kind() != reflect.Ptr {
		log.Error("rpc listen service pointer required")
		return
	}
	serviceName := msgType.Elem().Name()

	log.Info("%s service listen:%s", serviceName, host)
	rpcsrv := rpc.NewServer()
	rpcsrv.Register(service)

	ls, e := net.Listen("tcp", host)
	if e != nil {
		log.Error("service listen error:%v", e)
		return
	}

	rpcsrv.HandleHTTP("/"+serviceName, "/"+serviceName+"dbg")
	rpcsrv.Accept(ls)
}

func Get(host string) *rpc.Client {
	var c *rpc.Client
	rwRPCs.RLock()
	c, ok := rpcs[host]
	rwRPCs.RUnlock()

	if !ok {
		conn, err := net.DialTimeout("tcp", host, time.Second*1)
		if err != nil {
			log.Error("dialing:", err)
			return nil
		}
		cl := rpc.NewClient(conn)
		rwRPCs.Lock()
		rpcs[host] = cl
		rwRPCs.Unlock()
		c = cl
	}
	return c
}

func Reset(host string) {
	rwRPCs.Lock()
	delete(rpcs, host)
	rwRPCs.Unlock()
}
